//deck.cpp
//by Eric Norton
//2/13/02

#include "deck.h"

Deck::Deck()
{
	srand(Fulldeck.Time());		//seed random number generator
	rgCShands=NULL;				//no hands exist
	idrawn=0;					//no Cards drawn
	inumhands=0;				//zero hands
}

void Deck::Zapdeck()
{
	int ix;		//delete[] each hand

	Fulldeck.Zap();		//free Fulldeck
	for(ix=0;ix<inumhands;ix++)
	{
		rgCShands[ix].Zap();	//free all drawn Cards
	}
	delete[] rgCShands;		//reset pointers and variables
	rgCShands=NULL;
	idrawn=0;
	inumhands=0;
}

bool Deck::Sizeit(int inewsize)
{
	Card copycard;	//store newly generated Card
	int ix;			//[1,IRACE]
	int ideck;		//how many decks in Fulldeck?
	
	//see if in bounds
	if(inewsize<IMIN||inewsize>IMAX)
	{
		return false;
	}
	else
	{
		Zapdeck();	//free old Cards
		for(ideck=0;ideck<inewsize;ideck++)
		{
			copycard.csuit=CHEART;	//start in heart's suit
			while(copycard.csuit!=NULL)		//make race of each suit
			{
				for(ix=0;ix<IRACE;ix++)		//make each member of race
				{
					copycard.inum=ix+2;		//ix+2 FOR HORSERACE GAME
					Fulldeck.Give(copycard);	//put it on tail of Fulldeck
				}
				switch(copycard.csuit)	//switch to next suit
				{
				case CHEART:
					copycard.csuit=CDIAMOND;
					break;
				case CDIAMOND:
					copycard.csuit=CSPADE;
					break;
				case CSPADE:
					copycard.csuit=CCLUB;
					break;
				default:
					copycard.csuit=NULL;
					break;
				}

			}
		}
		return true;
	}
}

void Deck::Printdeck()
{
	Fulldeck.Print();
}

bool Deck::Handgen(int inum)
{
	//can't make negative #of hands
	if(inum<0)
	{
		return false;
	}
	else
	{
		Fulldiscard();	//put all Cards back in Fulldeck
		delete[] rgCShands;		//free old hands
		inumhands=inum;
		rgCShands=new Cardstack[inumhands];		//new #of hands
		return true;
	}
}

bool Deck::Draw(int ihand, int iCard)
{
	bool bval;
	
	ihand-=1;	//makes hands [1,n] instead of [0,n-1]
	//if out of bounds
	if(ihand<0||ihand>=inumhands||Fulldeck.isize<=0)
	{
		return false;
	}
	else
	{
		//take card from Fulldeck
		bval=rgCShands[ihand].Give(Fulldeck.Take(iCard));
		if(bval==true)
		{
			//if successful, one more card has been drawn from Fulldeck
			idrawn+=1;
		}

		return bval;
	}
}

bool Deck::Printhand(int ihand)
{
	ihand-=1;
	if(ihand<0||ihand>=inumhands)
	{
		return false;
	}
	else
	{
		rgCShands[ihand].Print();
		return true;
	}
}

bool Deck::Shuffle()
{
	//if no Cards are drawn
	if(idrawn==0)
	{
		return Fulldeck.Shuffle();
	}
	else
	{
		return false;
	}
}

bool Deck::Discard(int ihand, int iCard)
{
	ihand-=1;
	//check bounds
	if(ihand<0||ihand>=inumhands||iCard>rgCShands[ihand].isize||
		iCard<0||rgCShands[ihand].isize==0)
	{
		return false;
	}
	else
	{
		//return specified Card to Fulldeck
		Fulldeck.Give(rgCShands[ihand].Take(iCard));
		idrawn-=1;
		return true;
	}
}

void Deck::Fulldiscard()
{
	int ix=0;

	//free all hands
	while(ix<inumhands)
	{
		//free top Card while not empty
		while(rgCShands[ix].isize!=0)
		{
			Fulldeck.Give(rgCShands[ix].Take(0));
		}
		ix+=1;
	}
	idrawn=0;	//no Cards drawn
}

bool Deck::Handgive(int idonor, int iCard, int ithief, bool bhead)
{
	idonor-=1;
	ithief-=1;
	//check bounds
	if(idonor<0||ithief<0||idonor>=inumhands||ithief>=inumhands||
		iCard>rgCShands[idonor].isize||iCard<0)
	{
		return false;
	}
	else
	{
		//stick on head of ithief
		if(bhead==true)
		{
			rgCShands[ithief].Givehead(rgCShands[idonor].Take(iCard));
		}
		//stick on tail of ithief
		else
		{
			rgCShands[ithief].Give(rgCShands[idonor].Take(iCard));
		}
		return true;
	}
}

Card Deck::Getdeckcard(int inum)
{
	return Fulldeck.Getcard(inum);
}

Card Deck::Gethandcard(int ihand, int inum)
{
	Card copycard;

	//make QS default for error
	copycard.csuit=CSPADE;
	copycard.inum=12;

	ihand-=1;
	if(ihand<inumhands)
	{
		copycard=rgCShands[ihand].Getcard(inum);
	}

	return copycard;
}

int Deck::Getsize()
{
	return Fulldeck.isize;
}

int Deck::Gethandsize(int ihand)
{
	int ix=0;

	ihand-=1;
	if(ihand<inumhands&&ihand>=0)
	{
		return rgCShands[ihand].isize;
	}
	else
	{
		return -1;
	}
}

Deck::~Deck()
{
	Zapdeck();
}